#!/bin/bash
# 创建项目目录结构

mkdir -p server/src        # 服务端
mkdir -p server/include    # 头文件
mkdir -p server/bin        # 存储可执行文件
mkdir -p server/obj        # 存储过程文件
mkdir -p server/my_file    # 存储文件 例如 README.md 的图片
mkdir -p server/log        # 存储日志文件

mkdir -p client/src        # 客户端
mkdir -p client/include    # 头文件
mkdir -p client/bin        # 存储可执行文件
mkdir -p client/obj        # 存储过程文件
mkdir -p client/my_file    # 存储文件 例如 README.md 的图片
mkdir -p client/log        # 存储日志文件


# 创建头文件并添加防止重复编译的宏
create_header() {
    local header_file=$1
    local header_guard=$(basename $header_file | tr '[:lower:]' '[:upper:]' | tr '.' '_')
    echo "#ifndef __${header_guard}__" > $header_file
    echo "#define __${header_guard}__" >> $header_file
    echo "" >> $header_file
    echo "// 头文件内容" >> $header_file
    echo "" >> $header_file
    echo "#endif // __${header_guard}__" >> $header_file
}

# 创建服务器头文件
create_header "server/include/user.h"
create_header "server/include/udp.h"
create_header "server/include/tcp.h"
create_header "server/include/server.h"
create_header "server/include/utils.h"


# 创建客户端头文件
create_header "client/include/udp.h"
create_header "client/include/tcp.h"
create_header "client/include/client.h"
create_header "client/include/utils.h"


# 创建服务器源文件
touch server/src/server.c
touch server/src/user.c
touch server/src/tcp.c
touch server/src/udp.c
touch server/src/utils.c


# 创建客户端源文件
touch client/src/client.c
touch client/src/tcp.c
touch client/src/udp.c
touch client/src/utils.c


# 在每个 .c 文件中插入 #include "head.h"
add_include_to_client() {
    local c_file=$1
    echo '#include "client.h"' | cat - $c_file > temp && mv temp $c_file
}

add_include_to_server() {
    local c_file=$1
    echo '#include "server.h"' | cat - $c_file > temp && mv temp $c_file
}
# 在 服务器.c 中添加内容
cat > server/src/server.c<<EOL

int main(int argc, char const *argv[])
{
    printf("Hello, all students of HQYJ_24071!\n");
    return 0;
}
EOL
# 在 客户端.c 中添加内容
cat > client/src/client.c <<EOL

int main(int argc, char const *argv[])
{
    printf("Hello, all students of HQYJ_24071!\n");
    return 0;
}
EOL
#客户端
add_include_to_client "client/src/client.c"
add_include_to_client "client/src/tcp.c"
add_include_to_client "client/src/udp.c"
add_include_to_client "client/src/utils.c"

#服务器
add_include_to_server "server/src/server.c"
add_include_to_server "server/src/user.c"
add_include_to_server "server/src/tcp.c"
add_include_to_server "server/src/udp.c"
add_include_to_server "server/src/utils.c"

# 创建并写入 客户端.h 文件
cat > client/include/client.h <<EOL
#ifndef __CLIENT_H__
#define __CLIENT_H__

// 导入项目头文件
#include "udp.h"
#include "tcp.h"
#include "client.h"
#include "utils.h"

// 定义宏定义
#define LOG_FILE "client/log/error.log"                    // 报错日志文件



// 错误输出宏定义，写入日志文件并显示在终端
#define ERRLOG(msg) do { \
    time_t now = time(NULL); \
    char *timestr = ctime(&now); \
    timestr[strlen(timestr) - 1] = '\0'; /* 去掉末尾的换行符 */ \
    FILE *log_file = fopen(LOG_FILE, "a"); \
    if (log_file) { \
        fprintf(log_file, "[%s] 错误: %s\t文件: %s\t函数: %s\t行号: %d\n\n", \
                timestr, msg, __FILE__, __func__, __LINE__); \
        fclose(log_file); \
    } else { \
        fprintf(stderr, "错误: 无法打开日志文件: %s\n", LOG_FILE); \
    } \
    /* 输出到标准错误流 */ \
    fprintf(stderr, "[%s] 错误: %s\t文件: %s\t函数: %s\t行号: %d\n", \
            timestr, msg, __FILE__, __func__, __LINE__); \
} while (0)

#endif

EOL


# 创建并写入 服务器.h 文件
cat > server/include/server.h <<EOL
#ifndef __SERVER_H__
#define __SERVER_H__

// 导入项目头文件
#include "user.h"
#include "udp.h"
#include "tcp.h"
#include "server.h"
#include "utils.h"

// 定义宏定义
#define LOG_FILE "server/log/error.log"                    // 报错日志文件



// 错误输出宏定义，写入日志文件并显示在终端
#define ERRLOG(msg) do { \
    time_t now = time(NULL); \
    char *timestr = ctime(&now); \
    timestr[strlen(timestr) - 1] = '\0'; /* 去掉末尾的换行符 */ \
    FILE *log_file = fopen(LOG_FILE, "a"); \
    if (log_file) { \
        fprintf(log_file, "[%s] 错误: %s\t文件: %s\t函数: %s\t行号: %d\n\n", \
                timestr, msg, __FILE__, __func__, __LINE__); \
        fclose(log_file); \
    } else { \
        fprintf(stderr, "错误: 无法打开日志文件: %s\n", LOG_FILE); \
    } \
    /* 输出到标准错误流 */ \
    fprintf(stderr, "[%s] 错误: %s\t文件: %s\t函数: %s\t行号: %d\n", \
            timestr, msg, __FILE__, __func__, __LINE__); \
} while (0)

#endif

EOL


# 产生 Makefile 文件
cat > server/Makefile <<EOL
# 编译器
CC = gcc

# 编译选项
CFLAGS = -Wall -g -I./include

# 目标文件
TARGET = ./bin/Chat_Room_system_server

# 源文件目录和对象文件目录
SRC_DIR = ./src
OBJ_DIR = ./obj

# 源文件和对应的对象文件
SRCS = \$(wildcard \$(SRC_DIR)/*.c)
OBJS = \$(patsubst \$(SRC_DIR)/%.c, \$(OBJ_DIR)/%.o, \$(SRCS))

# 目标: 生成可执行文件
\$(TARGET): \$(OBJS)
	\$(CC) \$(CFLAGS) -o \$@ \$^

# 生成对象文件
\$(OBJ_DIR)/%.o: \$(SRC_DIR)/%.c
	\$(CC) \$(CFLAGS) -c \$< -o \$@

# 清理目标
.PHONY: clean
clean:
	rm -f \$(OBJ_DIR)/*.o \$(TARGET)
EOL


# 产生 Makefile 文件
cat > client/Makefile <<EOL
# 编译器
CC = gcc

# 编译选项
CFLAGS = -Wall -g -I./include

# 目标文件
TARGET = ./bin/Chat_Room_system_client

# 源文件目录和对象文件目录
SRC_DIR = ./src
OBJ_DIR = ./obj

# 源文件和对应的对象文件
SRCS = \$(wildcard \$(SRC_DIR)/*.c)
OBJS = \$(patsubst \$(SRC_DIR)/%.c, \$(OBJ_DIR)/%.o, \$(SRCS))

# 目标: 生成可执行文件
\$(TARGET): \$(OBJS)
	\$(CC) \$(CFLAGS) -o \$@ \$^

# 生成对象文件
\$(OBJ_DIR)/%.o: \$(SRC_DIR)/%.c
	\$(CC) \$(CFLAGS) -c \$< -o \$@

# 清理目标
.PHONY: clean
clean:
	rm -f \$(OBJ_DIR)/*.o \$(TARGET)
EOL

